<?php
namespace Ayhome\Suite\Command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;
use think\facade\Env;

use swoole_process;
class Queue extends Command
{
  protected $config = [];
  protected $queue = [];
  public function configure()
  {
    $this->setName('queue')
        ->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload", 'start')
        ->addOption('daemon', 'd', Option::VALUE_NONE, 'Run the swoole server in daemon mode.')
        ->setDescription('Swoole queue for ThinkPHP');
  }

  public function execute(Input $input, Output $output)
  {
    $action = $input->getArgument('action');
    $this->config = config('queue.');

    if ($this->input->hasOption('daemon')) {
      $this->config['daemonize'] = true;
    }

    if (empty($this->config['pid_file'])) {
      $this->config['pid_file'] = Env::get('runtime_path') . 'suite-queue.pid';
    }

    if (in_array($action, ['start', 'stop','restart'])) {
        $this->$action();
    } else {
        $output->writeln("<error>Invalid argument action:{$action}, Expected start|stop .</error>");
    }
  }

  public function start()
  {
    $pidFile = $this->config['pid_file'];

    if (file_exists($pidFile)) {
      $this->output->writeln('<error>suite crontab process is already running.</error>');
      return false;
    }


    $this->queue = new \FastD\Swoole\Queue('queue', function ($worker) {
      while (true) {
        $recv = $worker->pop();
        $v = json_decode($recv,true);
        print_r($v);
      }
    });

    if ($this->config['daemonize']) {
      // print_r('daemonize');
      $this->queue->daemon();
    }

    $pid = $this->queue->start();
    file_put_contents($pidFile, $pid);

    //读取任务
    // if ($this->config['database']) {
      // $tasks = db($this->config['database'])->select();
      $tasks = db('crontab')->select();
      $this->config['tasks'] = $tasks;
    // }

    $crontExpre = new \Ayhome\Suite\Parser\Crontab();
    swoole_timer_tick(1000, function ($id) use($crontExpre)  {
      $tasks = $this->config['tasks'];
      foreach ($tasks as $k) {
        if (!$k['cron']) continue;
        $sec = date('s');

        $r = $crontExpre::parse($k['cron']);
        if (!isset($r[$sec])) continue;

        $this->queue->push(json_encode($k));
      }
    });

    // $this->queue->wait(function ($ret) {
    //   echo 'PID: ' . $ret['pid'];
    //   // unlink($pidFile);
    // });
    return ;
  }

  public function restart()
  {
    $this->stop();
    $this->start();
    # code...
  }


  public function stop()
  {

    $pidFile = $this->config['pid_file'];
    if (is_file($pidFile)) {
      $pid = (int) file_get_contents($pidFile);
      $spid = $pid-1;
      swoole_process::kill($pid, SIGTERM);
      swoole_process::kill($spid, SIGTERM);
      unlink($pidFile);
    } else {
      $pid = 0;
    }
    return;
    
  }

}
